using System;
using System.Collections;
using Bullet;
using Enemy;
using Manager;
using UnityEngine;

namespace Player
{
    public class Player : MonoBehaviour
    {

        public static Player instance;

        [SerializeField] public float movementSpeed = 4f;
        [SerializeField]
        private bool isWalking;
        [SerializeField] private LayerMask enemyLayer; 
        private Animator anim;
        [SerializeField]
        private float range = 0.5f;//检测敌人范围
        public GameObject attackEnemy = null;
        [SerializeField]
        private float attackCooldown = 1f; // 攻击冷却
        [SerializeField]
        private float nextAttackTime; // 下次攻击的时间
        public GameObject point;//子弹发射点

        [Header("属性")]
        public float maxHp = 200f;
        public float hp = 200f;
        public float attackRange = 10f;//攻击数值
        public GameObject[] weapons;
        public int weaponIndex;//当前武器的下标

        [Header("摇杆")]
        public Joystick joystick;

        [Header("经验属性")] 
        [SerializeField] private int currentExperience; //当前经验值
        [SerializeField]private int maxExperience; //最大的经验值
        public int currentLevel;//当前等级
        [SerializeField]
        private int experienceAdd;//经验值增加
        public bool canUpdate;//是否可以更新经验值和UI
        [SerializeField]
        private GameObject talentPanel;
        
        private GameObject healthBar;
        private GameObject bulletPrefab;
        private GameObject damageNumPrefab;//恢复数值

        void Awake()
        {
            if (instance == null)
            {
                instance = this;
            }
            else
            {
                Destroy(gameObject);
            }

            //生成血条
            healthBar = Instantiate(Resources.Load<GameObject>("Prefabs/pfHealthBarUI"));
            healthBar.transform.SetParent(GameObject.Find("Canvas").transform);
            healthBar.GetComponent<HealthBar>().followTarget = gameObject;

            //要早于子弹的onenable
            point = transform.Find("point").gameObject;
        }

        private void OnEnable()
        {
            //自己订阅受伤的事件
            instance.OnPlayerGetHit += instance.PlayerGetHitHandler;
            
        }

        private void OnDisable()
        {
            //取消事件
            ExperienceManager.Instance.OnExperienceChanged -= HandleExperienceChanger;

            //取消自己订阅受伤的事件
            instance.OnPlayerGetHit -= instance.PlayerGetHitHandler;

            
            GameManager.Instance.OnEnemyNumIsZero -= HandleExperienceUpdate;
        }

        private void Start()
        {
            hp = maxHp;
            anim = GetComponent<Animator>();
            bulletPrefab = Resources.Load<GameObject>("Prefabs/Bullet/PlayerBullet");
            damageNumPrefab = Resources.Load<GameObject>("Prefabs/UI/damageNum");
            weapons[0].SetActive(true);


            //经验管理器在start里面调用，否则会报错
            if (ExperienceManager.Instance == null)
            {
                Debug.LogError("没有经验管理器");
                return;
            }

            //订阅事件
            ExperienceManager.Instance.OnExperienceChanged += HandleExperienceChanger;
            healthBar.GetComponent<HealthBar>().UpdateHp(hp / maxHp, hp);

            //订阅敌人数量为0的事件，为0时，更新经验值和UI
            GameManager.Instance.OnEnemyNumIsZero += HandleExperienceUpdate;

        }

        void Update()
        {
            Move();
            Attack();
            SwitchWeapon();
        }

        private void FixedUpdate()
        {
            CheckEnemy();
        }

        /// <summary>
        /// 获取攻击伤害
        /// </summary>
        /// <param name="isCriticalHit">返回是否暴击</param>
        /// <returns></returns>
        public float GetAttackRange(out bool isCriticalHit)
        {
            isCriticalHit = false;

            //50%的暴击
            if(UnityEngine.Random.Range(0, 100) <= 50)
            {
                isCriticalHit = true;
                return attackRange * 2;
            }
            return attackRange;
        }

        /// <summary>
        /// 设置攻击冷却时间
        /// </summary>
        /// <param name="offset"></param>
        public void SetAttackCoolDown(float offset)
        {
            float value = attackCooldown + offset;
            if(value <= 0)
            {
                attackCooldown = 0.1f;
            }else
                attackCooldown = value;
        }

        /// <summary>
        /// 添加血量
        /// </summary>
        /// <param name="offset"></param>
        public void AddHp(float offset)
        {
            float value = hp + offset;
            //显示玩家加血的数字
            DamageNum damageNum = PoolManager.Release(damageNumPrefab).GetComponent<DamageNum>();
            damageNum.SetPositon(transform.position + Vector3.one * UnityEngine.Random.Range(-0.5f, 0.5f));
            damageNum.ShowUIDamage(offset, true, false);

            if (value >= maxHp)
            {
                hp = maxHp;
            }else
                hp = value;
            healthBar.GetComponent<HealthBar>().UpdateHp(hp / maxHp, hp);
        }

        /// <summary>
        /// 切换武器
        /// </summary>
        /// <exception cref="NotImplementedException"></exception>
        private void SwitchWeapon()
        {
            
        }

        /// <summary>
        /// 玩家移动
        /// </summary>
        private void Move()
        {
#if UNITY_ANDROID
            //摇杆移动
            float horizontal = joystick.Horizontal;
            float vertical = joystick.Vertical;
#else
        float horizontal = Input.GetAxisRaw("Horizontal");
        float vertical = Input.GetAxisRaw("Vertical");
#endif
            float movementAmont = Mathf.Abs(horizontal) + Mathf.Abs(vertical);

            var movementInput = new Vector3(horizontal, 0, vertical).normalized;

            if(movementAmont > 0)//如果玩家在走，那么播放idle                                                        
            {
                isWalking = true;
                transform.position += movementInput * movementSpeed * Time.deltaTime;
                transform.rotation = Quaternion.LookRotation(movementInput);
            }
            else 
                isWalking = false;
            anim.SetBool("isWalking", isWalking);

        }


        /// <summary>
        /// 检测最近的敌人
        /// </summary>
        private void CheckEnemy()
        {
            float minDistance = Mathf.Infinity;
  
            Collider[] enemies = Physics.OverlapSphere(transform.position, range, enemyLayer);

            if(enemies.Length == 0)
            {
                attackEnemy = null;
                return;
            }

            foreach (var t in enemies)
            {
                float distance = Vector3.Distance(transform.position, t.transform.position);
                if(distance < minDistance)
                {
                    attackEnemy = t.gameObject;
                    minDistance = distance;
                }
            }

            if (attackEnemy != null)
            {               
                attackEnemy.GetComponent<BaseEnemy>().indicator.SetActive(true);
                //不要让indicator跟着敌人旋转
                
                for (int i = 0; i < enemies.Length; i++)
                {
                    if (enemies[i].gameObject != attackEnemy)
                    {
                        enemies[i].gameObject.GetComponent<BaseEnemy>().indicator.SetActive(false);
                    }
                }
            }

        }

        private void OnDrawGizmos()
        {
            Gizmos.color = Color.magenta;
            Gizmos.DrawWireSphere(transform.position, range);                                                      
        }

        /// <summary>
        /// 攻击
        /// </summary>
        public void Attack()
        {

            if (attackEnemy == null) return;
            if (!isWalking && Time.time >= nextAttackTime)
            {
                //朝向敌人
                // 面向敌人方向，只改变Y轴旋转

                Vector3 targetDirection = attackEnemy.transform.position - transform.position;
                targetDirection.y = 0; // 忽略Y轴方向
                Quaternion targetRotation = Quaternion.LookRotation(targetDirection);
                transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles.x, targetRotation.eulerAngles.y, transform.rotation.eulerAngles.z);
                //创建子弹
                StartCoroutine(CreateBullet());
                //播放攻击动画
                //anim.Play("Attack");
                anim.SetTrigger("attack");
                //播放音效
                AudioManager.instance.PlayPlayerShoot();
                nextAttackTime = Time.time + attackCooldown;

            }
        }


        /// <summary>
        /// 创建子弹
        /// </summary>
        /// <returns></returns>
        IEnumerator CreateBullet()
        {

            /*
            //利用Instantiate来生成子弹
            GameObject bullet = Instantiate(Resources.Load<GameObject>("Prefabs/Bullet/Bullet"));
            bullet.GetComponent<Bullet.Bullet>().Target = AttackEnemy.transform.position;
            yield return new WaitForSeconds(1f);
            */
            //利用对象池来管理子弹
            GameObject bullet = PoolManager.Release(bulletPrefab);
            bullet.GetComponent<Bullet.Bullet>().Target = attackEnemy.transform.position;
            yield return new WaitForSeconds(1f);
        }

        /// <summary>
        /// 玩家受伤事件
        /// </summary>
        public event Action<float> OnPlayerGetHit;

        public void PlayerGetHitHandler(float hitNum)
        {
            hp -= hitNum;
            if (hp <= 0)
            {
                Destroy(healthBar);
                Destroy(gameObject);
            }

            healthBar.GetComponent<HealthBar>().UpdateHp(hp / maxHp, hp);
        }

        /// <summary>
        /// 外部调用订阅玩家受伤事件
        /// </summary>
        /// <param name="num"></param>
        public void HitPlayer(float hitNum)
        {
            OnPlayerGetHit?.Invoke(hitNum);
        }
/*
        //子弹触发器
        private void OnTriggerEnter(Collider other)
        {
            if(other.gameObject.CompareTag("EnemyBullet"))
            {
                hp -= other.gameObject.GetComponent<BaseEnemy>().AttackRange;
            }
            if (hp <= 0)
            {
                Destroy(healthBar);
                Destroy(gameObject);
            }

            healthBar.GetComponent<HealthBar>().UpdateHp(hp / maxHp, hp);
        }*/
/*       
        /// <summary>
        /// 碰到敌人受伤
        /// </summary>
        /// <param name="collision"></param>
        public void OnCollisionEnter(Collision collision)
        {
            if (collision.gameObject.CompareTag("EnemyAttack"))
            {
                Debug.Log("玩家受伤");
                hp -= collision.gameObject.GetComponent<BaseEnemy>().AttackRange;
            }
            
            if (hp <= 0)
            {
                Destroy(healthBar);
                Destroy(gameObject);
            }

            healthBar.GetComponent<HealthBar>().UpdateHp(hp / maxHp, hp);

        }*/
        
        /// <summary>
        /// 经验值处理
        /// </summary>
        public void HandleExperienceChanger(int newExperience)
        {
            currentExperience += newExperience;
           
        }

        /// <summary>
        /// 经验值更新处理
        /// </summary>
        public void HandleExperienceUpdate()
        {
            //更新经验值
            ExperienceBar.Instance.UpdateExperienceAmount((float)currentExperience / maxExperience);
            //更新经验值和UI，判断是否升级
            ExperienceBar.Instance.UpdateExperience();
        }

        /// <summary>
        /// 等级升级
        /// </summary>
        /// <exception cref="NotImplementedException"></exception>
        public void LevelUp()
        {
            currentLevel++;
            currentExperience = 0;
            maxExperience += 100;
            //Time.timeScale = 0f;
            //显示天赋选择面板
            //talentPanel.SetActive(true);
        }
    }
    
}
